<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      //    练习题 1：创建计数器
      // 编写一个函数，该函数返回一个计数器对象，每次调用对象的 increment 方法时，计数器的值加一。要求使用闭包来保持计数器的状态。AG注释

      // function createCounter() {
      //   let count = 0;
      //   // 你的代码
      //   return {
      //     count, // 这是一个新定义的属性，它的值在对象被创建时被设置
      //     increment() {
      //       count++; // 这个 count 是函数内部的局部变量，通过闭包访问
      //     },
      //     getCount() {
      //       return count; // 这个 count 是通过闭包访问的局部变量
      //     },
      //   };
      // }

      // const counter = createCounter();
      // console.log(counter.count); // 初始值应该为 0
      // console.log(counter.getCount()); //应该为 0
      // counter.increment();
      // console.log(counter.count); // 这里是0
      // console.log(counter.getCount()); //这里是1
      // counter.increment();
      // const counter2 = createCounter();
      // console.log(counter2.count); // 初始值应该为 0
      // console.log(counter2.getCount()); //应该为 0
      // counter2.increment();
      // console.log(counter2.count); // 这里是0
      // console.log(counter2.getCount()); //这里是1

      // console.log(counter.getCount());//2

      /*
      总结：
      count 这是一个新定义的属性，它的值在对象被创建时被设置
      getCount()是个方法，用来获取count的值
      通过返回对象的方式是无法获取到最新的count值，只能获取到初始值0
      通过闭包来实现，通过闭包访问的局部变量，可以获取到最新的count值

      counter1和counter2是两个不同的计数器对象，它们分别拥有自己的计数器值。


      闭包也可以通过类的方式实现相同的功能，但是看场景，

      闭包：面向过程，小而巧，
      类：面向对象，大而强，封装，复用，开销较大
      */

      // 用类的方式实现
      // class Counter {
      //   constructor() {
      //     this.count = 0;
      //   }
      //   increment() {
      //     this.count++;
      //   }
      //   getCount() {
      //     return this.count;
      //   }
      // }

      // 用函数的方式实现
      // function createCounter() {
      //   let count = 0;
      //   function getCount() {
      //     return count;
      //   }
      //   function increment() {
      //     count++;
      //   }
      //   return {
      //     getCount,
      //     increment,
      //   };
      // }
      // 严格模式
      // "use strict";
      function createCounter() {
        console.log(this);// 严格模式下，this是undefined,非严格模式下是windows
        this.count = 0;
        function getCount() {
          return this.count;
        }
        function increment() {
          this.count++;
        }
        return {
          count: this.count,
          getCount,
          increment,
        };
      }
      const counter = new createCounter();
      console.log(counter);
      console.log(counter.count); // 初始值应该为 0
      console.log(counter.getCount()); //应该为 0
      counter.increment();
      console.log(counter.count); // 这里是0
      console.log(counter.getCount()); //这里是1
      console.log("===================================="); //这里是1
      const counter1 = createCounter();
      console.log(counter1); //
      console.log(counter1.increment());
      console.log(counter1.getCount());
    </script>
  </body>
</html>
